package com.cskaoyan.javase.oop1._10static._1basic;

/**
 * static关键字的语法
 * 静态成员变量/静态成员方法
 *
 * static修饰成员变量被称之静态成员变量，简称静态变量
 * （没有static修饰称之为普通成员变量或成员变量）
 *
 * 静态成员变量的定义语法：
 * 需要定义在类的成员位置
 * 语法：
 * [访问权限修饰符] statics 数据类型 变量名;
 *      就是比成员变量,多了一个static修饰,但是语义就和成员变量完全不同了.
 *
 *  静态成员方法的定义语法：
 *  需要定义在类的成员位置
 * 语法：
 * [访问权限修饰符] statics 返回值类型 方法名(形参列表){
 *   //方法体
 * }
 *  就是比成员方法,多了一个static修饰,但是语义就和成员方法完全不同了.
 *
 * 以上，我们把静态成员变量和静态成员方法，统称为类的静态成员。
 * 类的成员: 类中成员变量 + 类中成员方法
 * 类的成员是属于对象的
 * 类的静态成员是属于类的
 *
 *
 * static修饰的静态成员的使用和普通成员是完全不同的：
 *
 * 静态成员变量的使用具有以下特点:
 *      1.和普通成员变量一样,都具有默认值（默认值和普通成员变量是一样的）
 *          默认初始化的过程也是永远最先执行的.
 *      2.静态成员变量属于类的，完全不需要/不依赖创建对象使用。
 *          既然不依赖于对象,也不是属于对象的
 *          那么就不要用"对象名."去访问它们(虽然可以访问)
 *      3.访问和使用静态成员变量禁止使用"对象名."，而应该使用"类名."！
 *      4.静态成员变量的访问/赋值/使用都不依赖于对象。
 *
 * 静态成员方法的使用具有以下特点:
 *      1.无需创建对象就可以直接通过类名点直接调用。
 *      2.同一个类中的static方法互相调用可以省略类名，直接用方法名调用。（这就是我们之前方法的调用）
 *
 *
 * 静态成员的访问并不依赖于创建对象，可以直接通过类名访问，其原因在于：
 * 随着类加载完毕，静态成员就存在，并且能够使用了！
 * static静态成员和类加载的过程息息相关
 * 而普通成员和new对象的过程息息相关
 *      1.静态成员变量在类加载过程中完成默认初始化具有默认值，然后进行一些其它赋值，类加载结束就可以访问了。
 *      2.静态成员变量的赋值也是先进行默认初始化，然后考虑其它赋值手段。
 *      3.静态成员方法的二进制指令集合在类加载过程也准备完毕，可以调用了。
 *
 * 现在我们知道了两个过程:
 *      1.类加载
 *      2.new对象过程
 * 这两个过程有什么关联?
 *      1.new对象必然触发类加载(这是一种类加载的时机),而且是类加载在前
 *          new对象在后
 *      2.类加载一定new对象吗?
 *          当然不是,因为类加载的时机还有一些其它的场景
 *          所以类加载后,并不一定是存在对象的
 *
 * 以上,我们已经知道了,访问类的静态成员,是和类加载相关的,在类加载过程中就要完成静态成员的初始化,那么:
 *      访问某个类的静态成员,该类要不要类加载?
 *      当然要,一旦访问某个类的静态成员,就需要触发该类的类加载
 *      类加载结束后,才能够进行访问
 *      这就是典型的类加载的时机
 * 类加载的时机目前学过三种了:
 *      1.new对象
 *      2.启动main方法
 *      3.访问类的静态成员
 *
 * (最重要的)
 *      类加载最重要的特点是只有一次(在一次程序运行的过程中)'
 *      既然类加载只有一次
 *      那么某个类的静态成员变量也只有一个,在整个类的全局是唯一的
 *      所以有些人,也会把静态成员变量称之为"全局变量"(了解)
 *
 *      成员变量是new一个对象,就有一份,从这个角度来说,它肯定不是全局变量
 *
 *
 * @since 15:49
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*A a = new A();
        System.out.println(a.num);

        // 尝试使用"对象名."访问静态成员
        // Static member 'com.cskaoyan.javase.oop1._10static._1basic.A.staticNum' accessed via instance reference
        System.out.println(a.staticNum);*/
        // 静态成员属于类,所以用"类名."访问
        System.out.println(A.staticNum);


       /* A a = new A();
        a.test();*/
        A.testStatic();

        test();
    }

    public static void test(){}
}

class A {
    static int staticNum;
    int num;

    public static void testStatic() {
    }

    public void test() {
    }

}